<!DOCTYPE html>
<meta charset="utf-8">
<title>Agilent Data</title>
<style>


    .background {
        fill: #eee;
    }

    text.active {
        font-weight: bold;
    }

    .node circle {
        fill: #fff;
        stroke: steelblue;
        stroke-width: 1.5px;
    }

    .node {
        font: 10px sans-serif;
    }

    .link {
        fill: none;
        stroke: #ccc;
        stroke-width: 1.5px;
    }

</style>
<script src="http://d3js.org/d3.v2.min.js?2.8.1"></script>
<script src="clusterfck.js"></script>
<script src="http://code.jquery.com/jquery-1.8.3.js"></script>

<h1><i>Agilent Data</h1>

<aside style="margin-top:20px;">
    <p>Order: <select id="order">
            <option value="name">by Name</option>
            <option value="count">by Value</option>
            <option value="group">by Cluster</option> 
        </select>

</aside>
<div id="center"><table>
        <div id="chart"></div>
        </td>
    </table>
</div>
<script>


    var clusters = [];
    var margin = {top: 40, right: 0, bottom: 10, left: 140},
    width = 1000,
    height = 500;

    var x1 = d3.scale.ordinal().rangeBands([0, width]),
    y1 = d3.scale.ordinal().rangeBands([0, height]);

    var svg = d3.select("#chart").append("svg")
    .attr("width", width + margin.left + margin.right)
    .attr("height", height + margin.top + margin.bottom)
    .style("font-size", '11px')
    .style("font-weight", 'bold')
    .style("font-family", 'arial')
    .append("g")
    .attr("transform", "translate(" + margin.left + "," + margin.top + ")");

    // retrieve csv data from agilent table
    var phpfile = "";
    if( $("#cond").val() == 'undefined' ) {
        phpfile = "agilent_inf.php?cond=genes.species_ID=2";
    }
    else {
        phpfile = "agilent_inf.php?cond=" + $("#cond").val();
    }
    console.log("phpfile="+phpfile);
    var file = 'heatmap.csv?cond=genes.species_ID=2';
    console.log(file);
    d3.csv("heatmap.csv", function(csv) {
        var matrix = [];
        var exps = [];

        var idx_gsp = -1; // gene_symbol_probe index
        var gsn = []; // gene symbol names + probe name (rows)
        var hlink = []; // hyper link to link to box plot 
        var logbase = Math.log(2); // for log2 scaled expression value
        var idx_daydose = 0;
        var idx_day = 0;
        var daydose = []; // day and dose text 
        var col_day = []; // for displaying days on column 
        var col_dose = []; // for displaying doses on column
        var max_exp = -1; // maximum expression value
        // retrieve csv data from agilent table and populate data arrays to draw plot
        csv.forEach(function(x) {
            var gene_symbol_probe = x.gene_symbol + "_" + x.probe;
            var g = gsn.indexOf(gene_symbol_probe);
            if(g == -1) {
                g = ++idx_gsp;
                gsn[idx_gsp]=gene_symbol_probe;
                hlink[idx_gsp]='http://bardadb.org/plot/boxplot_table.php?symbol=' + x.gene_symbol + '&probe=' + x.probe;
                exps[g] = [];
                matrix[g] = [];
            }
	
            var s = exps[g].length;
            var val = Math.log(parseFloat(x.expression))/logbase;
            if(x.expression == '0') val = 0; 
            if(val > max_exp) max_exp = val;
            var key_daydose = x.day + ',' + x.dose;
            if(g == 0) {
                if(daydose.indexOf(key_daydose) < 0) {
                    daydose[idx_daydose++] = key_daydose;
                    col_dose[s] = x.dose;
                } else {
                    col_dose[s] = -1;
                }

                if(col_day.indexOf(x.day) < 0) {
                    col_day[s] = x.day;
                } else {
                    col_day[s] = -1;
                }
            }
            matrix[g].push({x: g, y: s}); //create columns and rows of the matrix
            exps[g].push(val); // push expression value into each row to display color on each cell
        });
        console.log(matrix);

        // mean computation for each row
        var mean = [];
        for(i=0;i<exps.length;i++) {
            var sum = 0;
            for(j=0;j<exps[i].length;j++) {
                sum += exps[i][j];
            }
            mean[i] = sum/exps[i].length;
        }
        // stdev computation for each row
        var stdev = [];
        for(i=0;i<exps.length;i++) {
            var sum = 0;
            for(j=0;j<exps[i].length;j++) {
                sum += Math.pow(exps[i][j]-mean[i],2);
            }
            stdev[i] = Math.sqrt(sum/exps[i].length);
        }
        // zscore computation
        var zscore_range = [];
        var max_zscore = [];
        var min_zscore = [];
        for(i=0;i<exps.length;i++) {
            max_zscore[i] = -Infinity;
            min_zscore[i] = Infinity;
            for(j=0;j<exps[i].length;j++) {
                zscore = (exps[i][j] - mean[i])/stdev[i];
                if( zscore > max_zscore[i] ) max_zscore[i] = zscore;
                if( zscore < min_zscore[i] ) min_zscore[i] = zscore;
            }
            zscore_range[i] = d3.scale.linear().domain([min_zscore[i],max_zscore[i]]).range(["white", "green"]);
        }
   
        // set range for each row
        exp_range = d3.scale.linear().domain([0,max_exp]).range(["white", "green"]);

        // column and row data 
        var col_data = [];
        var row_data = [];
        for(i=0;i<exps[0].length;i++)
            col_data[i] = i;
        for(i=0;i<gsn.length;i++)
            row_data[i] = i;
   
        // this is for sorting
        var orders = {
            name: d3.range(row_data.length).sort(function(a, b) { return d3.ascending(gsn[a], gsn[b]); }), // sort by gene_symbol_probe name (default) 
            count: d3.range(row_data.length).sort(function(a, b) { return mean[b] - mean[a]; }) // sort by mean  
        };

        // The default sort order.
        y1.domain(orders.name);
        x1.domain(col_data);

        // display Day and Gy
        svg.append("text")
        .attr("y", -20)
        .attr("x", -25)
        .text('Day');
        svg.append("text")
        .attr("y", -7)
        .attr("x", -25)
        .text('Gy');

        // create rectangle
        svg.append("rect")
        .attr("class", "background")
        .attr("width", width)
        .attr("height", height);

        var row = svg.selectAll(".row")
        .data(matrix)
        .enter().append("g")
        .attr("class", "row")
        .attr("transform", function(d, i) { return "translate(0,"  + y1(i) + ")"; })
        .each(row);
        console.log(matrix);
      
        // we need to show different color for different cluster 

        var column = svg.selectAll(".column")
        .data(col_data)
        .enter().append("g")
        .attr("class", "column")
        .attr("transform", function(d, i) { return "translate(" + x1(i) + ",0)"; });
        console.log(col_data);
        column.append("line")
        .attr("y2", height)
        .attr("stroke", function(d,i) {if( col_dose[i] != - 1) return 'white'; });

        var colorgroup = new Array(11);
        colorgroup['0.0'] = "#FF0000";
        colorgroup['1.0'] = "#FF6600";
        colorgroup['1.5'] = "#FF8533";
        colorgroup['2.0'] = "#FF9933";
        colorgroup['3.0'] = "#FFCC00";
        colorgroup['4.0'] = "#99CC00";
        colorgroup['5.0'] = "#009933";
        colorgroup['5.5'] = "#66CCFF";
        colorgroup['6.0'] = "#000066";
        colorgroup['6.5'] = "#1919A3";
        colorgroup['7.0'] = "#4747A3";
        colorgroup['10.0'] = "#8383AC";

        // display different color for day and dose
        column.append("text")
        .attr("y", -6)
        .attr("text-anchor", "start")
        .style("font-size", '12px')
        .style('fill', function(d,i) { if(col_dose[i] != -1) return colorgroup[col_dose[i]]; })
        .text(function(d, i) { if(col_dose[i] != -1) return col_dose[i]; }); 
        
        column.append("text")
        .attr("y", -18)
        .style("font-size", '12px')
        .attr("text-anchor", "start")
        .text(function(d, i) { if(col_day[i] != - 1) return col_day[i]; }); 

        // for each row, create cell and fill color according to its expression value
        function row(row) {
            console.log(row);
            var cell = d3.select(this).selectAll(".cell")
            .data(row) 
            .enter().append("rect")
            .attr("class", "cell")
            .attr("x", function(d) {return x1(d.y); })
            .attr("width", x1.rangeBand())
            .attr("height", y1.rangeBand())
            .style("fill", function(d) { return zscore_range[d.x]((exps[d.x][d.y]-mean[d.x])/stdev[d.x]); });
        }

        // for order selection combobox
        d3.select("#order").on("change", function() {
            order(this.value);
        });

        function order(value) {

            // cluster option is selected, show the dendogram
            if( value == 'group' ){
                y1.domain(grp);
                d3.select("#fig").style('display','inline');
            }
            else {
                // the other option is selected, hide the dendogram
                y1.domain(orders[value]);
                d3.select("#fig").style('display','none');
            }

            var t = svg.transition().duration(2500);

            // when count is selected, the color of each cell is zscore
            t.selectAll(".row")
            .delay(function(d, i) { return x1(i); })
            .attr("transform", function(d, i) { return "translate(0," + y1(i) + ")"; })
            .selectAll(".cell")
            .attr("x", function(d, i) { return x1(i); })
            .style("fill", function(d) { if(value == "count") return exp_range(exps[d.x][d.y]); else return zscore_range[d.x]((exps[d.x][d.y]-mean[d.x])/stdev[d.x]); });

        }

    });

</script>
